<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body{
            padding-bottom: 800px;
        }
        .box{
            border: 1px solid black;
            padding: 20px;
        }
    </style>
</head>
<body>
    <div id="app" class="box">
        <!-- 
        父组件向子组件数据传递
            技术实现：属性绑定，数据拦截
            详细描述：
                属性绑定=>以属性绑定的方式将传递的数据绑定在子组件标签上
                数据拦截=>在子组件对象中 以属性 props 方式进行 绑定属性的拦截获取
            实现原理：
                子组件标签被定义于父组件容器中，所以在子组件标签上通过v-bind绑定的数据可以正常读取父组件的数据；
                因为子组件标签最终会被替换为组件实例创建后的DOM元素，所以vue将子组件标签上的属性原封不动态传递到子组件的容器根元素上；
                子组件的容器标签属于子组件的调用范围，所以在子组件中可以通过读取属性的方式获取到传入的结果

                为了保持传递的数据响应功，vue在子组件创建的过程中，将所有定义于子组件标签上的属性转存(保持响应关联)到了组件实例的 $attrs 上
            
                vue 提供 props 属性，通过取值 数组并定义属性名，描述需要从 $attrs 中加载的数据变量，并提供类似于data仓库的取值使用规则;
                !!! 需要注意是的 props为破坏性获取，一旦使用了props定义属性，原标签上的属性和$attrs的属性都会被直接移除( 模块化中工具组件的定义用法 )
                !!! props 为只读获取
                !!! props:Array|Object
        -->
        <p>父组件</p>
        <p>msg:{{ msg }}</p>
        <p v-bind:msg="msg">属性绑定</p>
        <input type="text" v-model="msg">
        <!-- 子组件标签也是标签 -->
        <comp-one v-bind:msg="msg"></comp-one>
    </div>

    <script type="text/x-template" id="compOne">
        <div class="box" ref="divDom">
            <p>子组件</p>
            <p>msg:{{ msg }}</p>
            <p>$attrs.msg:{{ $attrs.msg }}</p>
        </div>
    </script>

    <script type="module"> 
        import { createApp } from "../../assets/vue3/vue.esm-browser.js";
        const app = createApp({
            data(){
                return {
                    msg:"父组件的数据变量msg"
                }
            }
        })

        app.component("CompOne",{
            template:"#compOne",
            // data() {
            //     return {
            //         msg: ""
            //     }
            // },
            // 从子组件标签上读取的具有响应关联的传递数据，作为特殊仓库被子组件使用
            props:["msg"],
            mounted () {
                // 缺失响应
                console.log( this.$refs.divDom.getAttribute("msg") )
                // this.msg = this.$refs.divDom.getAttribute("msg")
                // 保持响应记录的组件标签上的属性数据
                console.log(this.$attrs)
            },
        })

        app.mount("#app")
    </script>
</body>
</html>